package part2.task1;

import java.util.concurrent.*;

public class Main {
    public static final Function sin = new Function() {
        @Override
        public double call(double x) {
            return Math.sin(x);
        }
    };

    public static void main(String[] args) throws InterruptedException, ExecutionException {
        int n=8;
        int N=2000000;
        int startX=-N;
        double taskStep=(2*N+1)/n;
        Future<Double> tasks[]=new Future[n];

        ExecutorService executor= Executors.newFixedThreadPool(n);


        for (int i = 0; i < n; i++,startX+=taskStep) {
            tasks[i]=executor.submit(new CallableTask(sin,startX,i==n-1?N+1:startX+taskStep,1));
        }

        double sum=0;
        for (Future<Double> task:tasks){
            sum+=task.get();
        }

        System.out.println("Sum of sin(x) where x from "+-N+" to "+N+" on is: "+sum+" "+n);
    }
}

interface Function {
    double call(double x);
}

class CallableTask implements Callable<Double>{
    private Function function;
    private double startX, endX, stepX;
    private volatile double result;

    public CallableTask(Function function, double startX, double endX, double stepX){
        this.function=function;
        this.startX=startX;
        this.endX=endX;
        this.stepX=stepX;
    }

    @Override
    public Double call() throws Exception {
        double sum=0;
        for (double x = startX; x <endX; x+=stepX) {
            sum+=function.call(x);
        }
        result=sum;
        return result;
    }
}